package org.flexthinker.binding.value.support
{
    import org.flexthinker.binding.value.ValueModel;

    import mx.utils.StringUtil;

    /**
     * A simple value model that contains a single value. Notifies listeners when
     * the contained value changes.
     * The difference compared to ChangeWatcher, is that, despide custom events for [Bindable] metadata
     * the listeners always receive a PropertyChangeEvent with oldValue and newValue.
     */
    public class ValueHolder extends AbstractValueModel implements ValueModel
    {
        private var _value:Object;

        public function ValueHolder( host:Object, propertyName:String )
        {
            super(host, propertyName);
            updateValueProperty();
        }

        override public function getValue():Object
        {
            return _value;
        }

        override public function setValue( value:Object ):void
        {
            if ( hasValueChanged(_value,value))
            {
                var oldValue:Object = _value;
                _value = value;
                updateHostProperty(); // make sure the actual property is updated too
                fireValueChange(oldValue, _value);
            }
        }

        // --------------------
        //   internal methods
        // --------------------

        private function updateValueProperty():void
        {
            if ( !host || !propertyName || !host.hasOwnProperty(propertyName))
            {
                return;
            }
            _value = host[propertyName];
        }

        private function updateHostProperty():void
        {
            if ( !host || !propertyName || !host.hasOwnProperty(propertyName))
            {
                return;
            }
            host[propertyName] = _value;
        }
    }
}